#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
#define LL long long
#define ULL unsigned long long

const int N = 1e5+10;
int n, m, st[N*10], cnt;
LL L, V, pos[N];
struct node
{
    LL d, v, a;
}a[N];
struct Line
{
    LL l, r;
}lines[N];

inline void init()
{
    cnt = 0;
    for (int i = 0; i <= L; i++) st[i] = 0;
    scanf("%d%d%lld%lld", &n, &m, &L, &V);
    for (int i = 1; i <= n; i++) scanf("%lld%lld%lld", &a[i].d, &a[i].v, &a[i].a);
    for (int i = 1; i <= m; i++) scanf("%lld", &pos[i]), st[pos[i]] = 1;
    for (int i = 1; i <= L; i++) st[i] += st[i-1];
}

inline bool check(int l, int r)
{
    if (l == 0) return st[r] > 0;
    return (st[r] - st[l-1]) > 0;
}

inline bool in(int x, int ind)
{
    return lines[ind].l <= pos[x] && pos[x] <= lines[ind].r;
}

inline void solve()
{
    LL ans = 0;
    for (int i = 1; i <= n; i++)
    {
        // case 1
        if (a[i].v <= V && a[i].a <= 0) continue;
        // case 2
        else if (a[i].v > V && a[i].a >= 0)
        {
            if (check(a[i].d, L))
            {
                // cout << i << endl;
                lines[++cnt] = {a[i].d, L};
                ++ans;
            }
        }
        // case 3
        else if (a[i].v <= V && a[i].a > 0)
        {
            LL cur = (LL) ceil((V - a[i].v) * (V + a[i].v) / (2.0 * a[i].a)) + a[i].d;
            if ((V - a[i].v) * (V + a[i].v) % (2 * a[i].a) == 0) ++ cur;
            if (cur > L) continue;
            if (check(cur, L))
            {
                lines[++cnt] = {cur, L};
                // cout << i << endl;
                ++ans;
            }
        }
        // case 4
        else if (a[i].v > V && a[i].a < 0)
        {
            LL cur = a[i].d + ((V - a[i].v) * (V + a[i].v) / (2 * a[i].a));
            if (((V - a[i].v) * (V + a[i].v) % (2 * a[i].a)) == 0) --cur;
            // cout << cur << " ";
            // cout << a[i].d << " " << cur << endl;
            cur = min(cur, L);
            cur = min(cur, a[i].d - (a[i].v * a[i].v) / (2 * a[i].a));
            // cout << cur << endl;
            if (check(a[i].d, cur))
            {
                // cout << i << endl;
                lines[++cnt] = {a[i].d, cur};
                ++ ans;
            }
        }
    }

    int mn = m;
    for (int i = 1; i < (1<<m); i++)
    {  
        int val = 0;
        for (int j = 0; j < m; j++)
            if (i&(1<<j)) ++ val;
        bool can = true;
        for (int j = 1; j <= cnt; j++)
        {
            bool flag = false;
            for (int t = 1; t <= m; t++)
            {
                if (i & (1<<(t-1)) && in(t, j))
                {
                    flag = true;
                    break;
                }
            }
            if (!flag)
            {
                can = false;
                break;
            }
        }
        if (can)
        {
            mn = min(mn, val);
            break;
        }
    }
    printf("%lld %d\n", ans, m - mn);
}

int main()
{
    freopen("detect.in", "r", stdin);
    freopen("detect.out", "w", stdout);

    int T; scanf("%d", &T);
    while (T--)
    {
        init();
        solve();
    }

    return 0;
}